package com.du.dupload;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class ProcessManager implements ManagerCallback, IUICallbackHandler {
	enum State {
		READY, DOWNLOADING, CONVERTING, UPLOADING, DONE
	}

	enum Progress {
		PROGRESS, TERMINATED, FINISHED
	}

	private TasksManager tm;
	private State state;
	private Progress progress = Progress.PROGRESS;
	private IUICallback ui;
	private IResourceDownloader rd;
	private List<IVideoSplitter> videoSplitters;
	private List<IVideoUploader> videoUploaders;
	private List<String> pathToFileToBeSplitted;
	private List<String> pathToFileToBeUploaded;
	private List<String> finalResult;
	private ILoader downloader;
	private ISplitter splitter;
	private IUploader uploader;
	private Integer status;

	ProcessManager(IUICallback ui, IResourceDownloader rd, TasksManager tm) {
		super();
		state = State.READY;
		this.ui = ui;
		this.rd = rd;
		this.tm = tm;
		ui.setCallback(this);
	}

	ProcessManager(IUICallback ui, List<String> paths, TasksManager tm) {
		super();
		state = State.DOWNLOADING;
		this.ui = ui;
		this.pathToFileToBeSplitted = paths;
		this.tm = tm;
		ui.setCallback(this);
		videoSplitters = new ArrayList<IVideoSplitter>();
		for (String path : pathToFileToBeSplitted) {
			videoSplitters.add(new FFmpeg(path));
		}

	}

	ProcessManager(IUICallback ui, List<String> paths, TasksManager tm,
			boolean b) {
		super();
		state = State.UPLOADING;
		this.ui = ui;
		this.pathToFileToBeUploaded = paths;
		this.tm = tm;
		ui.setCallback(this);
		videoUploaders = new ArrayList<IVideoUploader>();
		for (String path : pathToFileToBeUploaded) {
			videoUploaders.add(new VKwrapper(path));
		}

	}

	public void continueTask() {
		if (progress == Progress.PROGRESS) {
			return;
		}
		if (progress == Progress.FINISHED) {
			doNextTask();
		}
		switch (state) {
		case READY:
			break;
		case DOWNLOADING:
			download();
			break;
		case CONVERTING:
			split();
			break;
		case UPLOADING:
			System.out.println("upload started");
			upload();
			break;

		}
	}

	private void doNextTask() {
		if (progress == Progress.PROGRESS) {
			return;
		}
		status = 0;
		switch (state) {
		case READY:
			download();
			break;
		case DOWNLOADING:
			split();
			break;
		case CONVERTING:
			upload();
			break;
		case UPLOADING:
			state = State.DONE;
			taskFinished("full completion");
			break;

		}
	}

	private void split() {
		if (ui == null || videoSplitters == null) {
			throw new IllegalStateException("smth not initialized");
		}
		splitter = new CustomSplitter(ui, videoSplitters, this);
		splitter.execute();
		state = State.CONVERTING;
		taskStarted("split started");

	}

	public void terminateCurrentTask() {
		if (progress == Progress.TERMINATED) {
			throw new IllegalStateException("can't terminate terminated task");
		}
		switch (state) {
		case READY:
			taskDisrupted("silence was terminated");
			break;
		case DOWNLOADING:
			terminateDownload();
			break;
		case CONVERTING:
			terminateSplitting();
			break;
		case UPLOADING:
			terminateUploading();
		}

	}

	private void terminateUploading() {
		uploader.cancel();
		taskDisrupted("upload terminated");

	}

	private void terminateSplitting() {
		splitter.cancel();
		taskDisrupted("splitting terminated");

	}

	private void terminateDownload() {
		downloader.cancel();
		taskDisrupted("download terminated");

	}

	private void download() {
		if (ui == null || rd == null) {
			throw new IllegalStateException("smth not initialized");
		}
		downloader = new CustomLoader(ui, rd, this);
		downloader.execute();
		state = State.DOWNLOADING;
		taskStarted("download started");
	}

	private void upload() {

		System.out.println("upload");
		if (ui == null || videoUploaders == null) {
			throw new IllegalStateException("smth not initialized");
		}
		uploader = new CustomUploader(ui, videoUploaders, this, status);
		uploader.execute();
		state = State.UPLOADING;
		taskStarted("upload started");
	}

	public void setSplitData(List<String> paths) {
		pathToFileToBeSplitted = paths;
		videoSplitters = new ArrayList<IVideoSplitter>();
		for (String path : paths) {
			System.out.println(path);
			if (path.endsWith(".mkv") || path.endsWith(".mp4")
					|| path.endsWith(".avi")) {
				videoSplitters.add(new FFmpeg(path));

			}
		}
	}

	public void setFinalData(List<String> paths) {
		finalResult = paths;

	}

	@Override
	public void currentTaskIsFinished(String info) {
		if (progress == Progress.TERMINATED) {
			return;
		}
		ui.setStatus(info);
		taskFinished("finished " + info);
		doNextTask();
	}

	// ui handlers
	@Override
	public void taskDisrupted(String reason) {
		progress = Progress.TERMINATED;
		ui.stopLoading();
		System.out.println("task disrupted");
		if (SwingContainer.getRestart()) {
			continueTask(); // do it again
		}

	}

	@Override
	public void taskStarted(String reason) {
		progress = Progress.PROGRESS;
		ui.startLoading("");

	}

	@Override
	public void taskFinished(String reason) {
		progress = Progress.FINISHED;
		ui.setFinished();
	}

	@Override
	public void setUploadData(List<String> paths) {
		Random rand = new Random();
		int randomNum = rand.nextInt(1);
		pathToFileToBeUploaded = paths;
		videoUploaders = new ArrayList<IVideoUploader>();
		for (String path : paths) {
			IVideoUploader uploader;
			System.out.println(path);
			switch(randomNum){
			case 0 :
				uploader = new VKwrapper(path);
				break;
			case 1:
				uploader = new VKwrapper(path);
				break;
			default:
				uploader = new VKwrapper(path);
			}
			
			videoUploaders.add(uploader);

		}

	}

	@Override
	public void reportStatus(Integer status) {
		this.status = status;

	}

}
